package com.bocloud.controller.user;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.bocloud.dto.ApiDto;
import com.bocloud.kong.KongConfig;
import com.bocloud.model.Result;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.bocloud.dto.LoginInfoDto;
import com.bocloud.enumeration.ArticleType;
import com.bocloud.framework.JsonResult;
import com.bocloud.framework.MyException;
import com.bocloud.framework.auth.AuthPassport;
import com.bocloud.framework.base.BaseController;
import com.bocloud.inter.service.table.IArticleService;
import com.bocloud.inter.service.table.IInterfaceService;
import com.bocloud.inter.service.table.IModuleService;
import com.bocloud.inter.service.table.IProjectService;
import com.bocloud.inter.service.table.IProjectUserService;
import com.bocloud.inter.service.table.IRoleService;
import com.bocloud.inter.service.table.ISourceService;
import com.bocloud.inter.service.table.IUserService;
import com.bocloud.inter.service.tool.ICacheService;
import com.bocloud.kong.model.Api;
import com.bocloud.kong.service.ApiService;
import com.bocloud.model.Interface;
import com.bocloud.model.Module;
import com.bocloud.springbeans.Config;
import com.bocloud.utils.Const;
import com.bocloud.utils.MyString;
import com.bocloud.utils.Page;
import com.bocloud.utils.Tools;

@Controller
@RequestMapping("/user/module")
public class ModuleController extends BaseController<Module> {

    @Autowired
    private IModuleService moduleService;
    @Autowired
    private ICacheService cacheService;
    @Autowired
    private IRoleService roleService;
    @Autowired
    private IArticleService articleService;
    @Autowired
    private IUserService userService;
    @Autowired
    private IInterfaceService interfaceService;
    @Autowired
    private IProjectService projectService;
    @Autowired
    private IProjectUserService projectUserService;
    @Autowired
    private ISourceService sourceService;
    @Autowired
    private ApiService apiService;
    @Autowired
    private Config config;
    @Autowired
    private KongConfig kongConfig;

    @RequestMapping("/list.do")
    @ResponseBody
    public JsonResult list(@ModelAttribute Module module, @RequestParam(defaultValue = "1") int currentPage)
            throws MyException {
        Page page = new Page(15);
        page.setCurrentPage(currentPage);
        Map<String, Object> map = Tools.getMap("projectId", module.getProjectId());

        hasPermission(cacheService.getProject(module.getProjectId()), view);

        List<Module> list = moduleService.findByMap(map, page, null);

        if(list!=null){
            for(Module module1:list){
                if(!MyString.isEmpty(module1.getKongApiUrl())) {
                    module1.setKongApiFullUrl(kongConfig.getKongHttpAddress() + module1.getKongApiUrl());
                }
            }
        }

        return new JsonResult(1, list , page);
    }

    @RequestMapping("/detail.do")
    @ResponseBody
    public JsonResult detail(@ModelAttribute Module module) throws MyException {
        Module model;
        if (!module.getId().equals(Const.NULL_ID)) {
            model = moduleService.get(module.getId());
            if (!MyString.isEmpty(model.getTemplateId())) {
                Interface inter = interfaceService.get(model.getTemplateId());
                if (inter != null)
                    model.setTemplateName(inter.getInterfaceName());
            }
            hasPermission(cacheService.getProject(model.getProjectId()), view);
        } else {
            hasPermission(cacheService.getProject(module.getProjectId()), view);
            model = new Module();
            model.setStatus(Byte.valueOf("1"));
            model.setProjectId(module.getProjectId());
        }
        return new JsonResult(1, model);
    }

    /**
     * 加载Kong api 信息
     */
    @RequestMapping("/up.do")
    @ResponseBody
    public JsonResult up(@ModelAttribute Module module) throws MyException {
        Module model = null;
        Api api = null;
        ApiDto apiDto = new ApiDto();
        if (!module.getId().equals(Const.NULL_ID)) {
            model = moduleService.get(module.getId());
            if(!MyString.isEmpty(model.getKongApiId())) {
                api = apiService.query(model.getKongApiId());
            }

            if (api == null || !MyString.isEmpty(api.getErrorMessage())) {
                api = new Api();
                api.setName(model.getId());
                api.setUpstream_url(model.getUrl());
            }

            BeanUtils.copyProperties(api,apiDto);
            apiDto.setModuleName(model.getName());
            apiDto.setProjectName(model.getProjectName());
        } else {
            return new JsonResult(0, null, "000099", "模块ID为空");
        }

        return new JsonResult(1, apiDto);
    }

    /**
     * 进行模块上线操作
     */
    @RequestMapping("/upAddOrUpdate.do")
    @ResponseBody
    public JsonResult upAddOrUpdate(@ModelAttribute ApiDto api) throws Exception {

        Module module = moduleService.get(api.getName());

        if (module == null) {
            return new JsonResult(0, null, "000099", "对应模块不存在【" + api.getModuleName() + "】");
        }

        if (MyString.isEmpty(module.getUrl())) {
            return new JsonResult(0, null, "000099", "模块【" + api.getModuleName() + "】的URL不能为空");
        }

        if (!module.getUrl().toLowerCase().startsWith("http://")
                && !module.getUrl().toLowerCase().startsWith("https://")) {
            return new JsonResult(0, null, "000099", "模块【" + api.getModuleName() + "】的URL必须以http://或https://开头");
        }

        Api newApi = new Api();

        BeanUtils.copyProperties(api,newApi);
        newApi.setUris(new String[]{"/" + module.getName()});

        if(MyString.isEmpty(module.getKongApiId())){
            newApi.setId(null);
        }else{
            newApi.setId(module.getKongApiId());
        }

        Result result = apiService.save(newApi);

        if (!result.isSuccess()) {
            return new JsonResult(0, null, "000099", result.getMessage());
        }else{
            module.setKongApiId(((Api)result.getData()).getId());
            module.setKongApiUrl("/" + newApi.getUris()[0]);
            moduleService.update(module);
            cacheService.delObj(Const.CACHE_MODULE + module.getId());
        }

        return new JsonResult(1, api);
    }

    @RequestMapping("/addOrUpdate.do")
    @ResponseBody
    public JsonResult addOrUpdate(@ModelAttribute Module module) throws Exception {
        // 系统数据，不允许删除
        if (module.getId().equals("web"))
            throw new MyException("000009");

        if (module.getUrl().endsWith("/"))
            module.setUrl(module.getUrl().substring(0, module.getUrl().length() - 1));
        hasPermission(cacheService.getProject(module.getProjectId()), addModule);
        module.setUserId(Tools.getUser().getId());
        if(MyString.isEmpty(module.getId())) {
            moduleService.save(module);
        }else{
            moduleService.update(module);
        }

        cacheService.delObj(Const.CACHE_MODULE + module.getId());

        /**
         * 刷新用户权限
         */
        LoginInfoDto user = Tools.getUser();
        // 将用户信息存入缓存
        cacheService.setObj(Const.CACHE_USER + user.getId(),
                new LoginInfoDto(userService.get(user.getId()), roleService, projectService, projectUserService),
                config.getLoginInforTime());

        return new JsonResult(1, module);
    }

    /**
     * 设置模块接口
     *
     * @param id
     * @return
     * @throws Exception
     */
    @RequestMapping("/setTemplate.do")
    @ResponseBody
    public JsonResult setTemplate(String id) throws Exception {
        Interface inter = interfaceService.get(id);

        Module module = cacheService.getModule(inter.getModuleId());
        hasPermission(cacheService.getProject(module.getProjectId()), modModule);

        module.setTemplateId(inter.isTemplate() ? null : inter.getId());
        moduleService.update(module);

        interfaceService.update("update Interface set isTemplate=0 where moduleId ='" + module.getId() + "'", null);
        if (!inter.isTemplate()) {
            inter.setTemplate(true);
            interfaceService.update(inter);
        }

        cacheService.delObj(Const.CACHE_MODULE + module.getId());
        return new JsonResult(1, module);
    }

    /**
     * 下线网关api
     *
     * */
    @RequestMapping("/downApi.do")
    @ResponseBody
    public JsonResult downApi(@ModelAttribute Module module) throws Exception {
        // 系统数据，不允许删除
        Module tmp = moduleService.get(module.getId());
        if (tmp != null) {
            apiService.delete(tmp.getKongApiId());

            tmp.setKongApiUrl(null);
            tmp.setKongApiId(null);
            moduleService.update(tmp);

        }else{
            return new JsonResult(0, null, "000099", "对应模块不存在【" + module.getId() + "】");
        }
        return new JsonResult(1, null);
    }

    @RequestMapping("/delete.do")
    @ResponseBody
    public JsonResult delete(@ModelAttribute Module module) throws Exception {
        // 系统数据，不允许删除
        if (module.getId().equals("web"))
            throw new MyException("000009");

        Module oldDataCenter = cacheService.getModule(module.getId());
        hasPermission(cacheService.getProject(oldDataCenter.getProjectId()), delModule);

        if (interfaceService.getCount(Tools.getMap("moduleId", oldDataCenter.getId())) > 0) {
            throw new MyException("000024");
        }

        if (articleService
                .getCount(Tools.getMap("moduleId", oldDataCenter.getId(), "type", ArticleType.ARTICLE.name())) > 0) {
            throw new MyException("000034");
        }

        if (sourceService.getCount(Tools.getMap("moduleId", oldDataCenter.getId())) > 0) {
            throw new MyException("000035");
        }

        if (articleService
                .getCount(Tools.getMap("moduleId", oldDataCenter.getId(), "type", ArticleType.DICTIONARY.name())) > 0) {
            throw new MyException("000036");
        }

        cacheService.delObj(Const.CACHE_MODULE + module.getId());
        moduleService.delete(module);
//		apiService.delete(module.getId());
        return new JsonResult(1, null);
    }

    @RequestMapping("/changeSequence.do")
    @ResponseBody
    @AuthPassport
    public JsonResult changeSequence(@RequestParam String id, @RequestParam String changeId) throws MyException {
        Module change = moduleService.get(changeId);
        Module model = moduleService.get(id);

        hasPermission(cacheService.getProject(change.getProjectId()), modModule);
        hasPermission(cacheService.getProject(model.getProjectId()), modModule);

        int modelSequence = model.getSequence();
        model.setSequence(change.getSequence());
        change.setSequence(modelSequence);

        moduleService.update(model);
        moduleService.update(change);

        return new JsonResult(1, null);
    }

}
